package csel.controller.dispatchers;

import java.util.concurrent.LinkedBlockingQueue;

import csel.model.GameCommand;
import csel.model.Invoker;

/**
 * Purpose: This receives commands and passes them to the correct invoker
 * 
 * @author Nikolas Wolfe
 */

public class Dispatcher
{
	private final Invoker invoker;
	private final Thread worker;
	private final LinkedBlockingQueue<GameCommand> queue;
	
	public Dispatcher(Invoker invoker)
	{
		this.invoker = invoker;
		this.worker = new Thread(new Worker());
		this.queue = new LinkedBlockingQueue<GameCommand>();
	}
	
	public void registerCommand(GameCommand gameCommand)
	{
		try
		{
			queue.put( gameCommand );
		} 
		catch (InterruptedException e)
		{
			Thread.currentThread().interrupt();
		}
	}
	
	public void startDispatcher()
	{
		worker.start();
		System.out.println("Worker started!");
	}
	
	public void stopDispatcher()
	{
		worker.interrupt();
	}
	
	/**
	 * This defines a worker thread that dispatches commands sent to
	 * the Dispatcher
	 */
	private class Worker implements Runnable
	{
		public void run()
		{
			try
			{
				while (!Thread.interrupted())
				{
					invoker.accept(queue.take());
				}
			}
			catch (InterruptedException e)
			{
				Thread.currentThread().interrupt();
			}
			//System.out.println("Worker terminated.");
		}
	}
}
